package com.techwells.taco.networkaccessor;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.graphics.Bitmap;
import android.os.Environment;

import com.techwells.learningkites.cache.BaseUserCenter;
import com.techwells.learningkites.networkservice.Constant;
import com.techwells.taco.networkaccessor.HttpURLConnectionHelper.RequestZipType;
import com.techwells.taco.networkmodel.BaseUser;
import com.techwells.taco.parser.MockHandler;
import com.techwells.taco.parser.MockHandlerSucceedListener;
import com.techwells.taco.utils.ENVConfig;
import com.techwells.taco.utils.LogUtil;
import com.techwells.taco.utils.StreamUtil;
import com.techwells.taco.utils.UpdateUtil;

/**
 * 数据请求类
 * 
 * @author kyson
 * @discussion 请求使用的类是android推荐的HttpURLConnection类
 *             分六种请求，http,https,http支持gzip，https支持gzip,http支持认证，https支持认证
 *             非单例类，因为HttpURLConnection使用完必须close(调用disconnect函数)
 */
public class NetworkAccess {
	final static String TAG = "NetworkAccess";
	public static String venusUrl = ENVConfig.xmlParser == null ? ""
			: ENVConfig.xmlParser.getVenusURL();

	private static NetworkResponse doHttpRequest(String requestURL,
			String requestData, boolean isAuth, boolean isGzip, int requestMethod) {
		// 判断有无挡板数据
		final NetworkResponse resultResponse = new NetworkResponse();
		if (ENVConfig.mockState) {
			MockHandler mockHandler = new MockHandler();
			mockHandler
					.setRequestFinishedListener(new MockHandlerSucceedListener() {
						@Override
						public void responseFetched(String response) {
							// TODO Auto-generated method stub
							resultResponse.setWithData(response,
									HttpURLConnection.HTTP_OK, null);
						}
					});
			mockHandler.getDataFormMock(requestURL, requestData);
			return resultResponse;
		}
		HttpURLConnection urlConn = null;
		try {
			urlConn = HttpURLConnectionHelper.getNewHttpURLConnectionInstance(
					requestURL, requestData,
					isGzip ? RequestZipType.requestTypeGzip
							: RequestZipType.requestTypeUnzip, isAuth, requestMethod);

			LogUtil.d(TAG, "Request:" + requestURL.toString());
			LogUtil.d(TAG, "URL:" + urlConn.getURL().toString());
			LogUtil.d(TAG, "Params:" + requestData);

			if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				
				String resultString = HttpURLConnectionHelper
						.fetchHttpRequestData(urlConn);
				resultResponse.setWithData(resultString,
						HttpURLConnection.HTTP_OK, null);
				LogUtil.d(TAG, "Response:" + resultString);
//				 JSESSION
//				String key = null;
//				for (int i = 1; (key = urlConn.getHeaderFieldKey(i)) != null; i++) {
//					LogUtil.d(TAG, "JSESSION:" + urlConn.getHeaderField(i));
//				}
//				Captcha-VerifyType
//				Map<String, List<String>> map = urlConn.getHeaderFields();
//				 for (Map.Entry<String, List<String>> entry : map.entrySet())
//		            {
//					 LogUtil.d(TAG,"Key : " + entry.getKey() + " ,Value : " + entry.getValue());
//		            }
				

//				String cookieValue=urlConn.getHeaderField("Set-Cookie"); 
//				String sessionId=cookieValue.substring(0, cookieValue.indexOf(";"));
//				LogUtil.d(TAG, "sessionId:" + sessionId);
				
				// 获取和保存JSESSIONID
				String cookieValue=urlConn.getHeaderField("Set-Cookie"); 
				if(cookieValue != null){
                	Constant.JSESSIONID = cookieValue.substring(cookieValue.indexOf("=") + 1, cookieValue.indexOf(";"));
                }
				LogUtil.d(TAG, "JSESSIONID:" + Constant.JSESSIONID);
				
				// 获取和保存Captcha-VerifyType
				String cookieValue2=urlConn.getHeaderField("Captcha-VerifyType"); 
				if(cookieValue2 != null){
                	Constant.verifyType = cookieValue2.substring(cookieValue2.indexOf(":") + 1);
                }
				LogUtil.d(TAG, "Captcha-VerifyType:" + Constant.verifyType);

			} else if (urlConn.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) {

				String resultString = null;
				InputStream in = urlConn.getErrorStream();
				resultString = StreamUtil.convertStreamToString(in);
				in.close();
				resultResponse
						.setWithData(resultString, urlConn.getResponseCode(),
								urlConn.getResponseMessage());
				LogUtil.d(TAG + "返回ResponseCode：401", urlConn.getResponseCode()
						+ ":" + urlConn.getResponseMessage() + resultString);
			}
			/*
			 * 预留接口
			 */
			// else if (urlConn.getResponseCode() ==
			// HttpURLConnection.HTTP_BAD_REQUEST) {
			// LogUtil.d("HttpError",
			// urlConn.getResponseCode() + ":"
			// + urlConn.getResponseMessage());
			// resultResponse.setWithData("", urlConn.getResponseCode(),
			// urlConn.getResponseMessage());
			// } else if (urlConn.getResponseCode() == 460) {
			// LogUtil.d("HttpError",
			// urlConn.getResponseCode() + ":"
			// + urlConn.getResponseMessage());
			// resultResponse.setWithData("", urlConn.getResponseCode(),
			// urlConn.getResponseMessage());
			// }
			else {
				LogUtil.d("HttpError", urlConn.getResponseCode() + ":"
						+ urlConn.getResponseMessage());
				resultResponse.setWithData("", urlConn.getResponseCode(),
						urlConn.getResponseMessage());
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			LogUtil.e(TAG, "Connection Error");
			e.printStackTrace();
		} finally {
			urlConn.disconnect();
		}
		return resultResponse;
	}
	
	
	public static NetworkResponse doHttpRequestJson(String requestURL,
			String requestData, boolean isAuth, boolean isGzip, int requestMethod) {
		// 判断有无挡板数据
		final NetworkResponse resultResponse = new NetworkResponse();
		if (ENVConfig.mockState) {
			MockHandler mockHandler = new MockHandler();
			mockHandler
					.setRequestFinishedListener(new MockHandlerSucceedListener() {
						@Override
						public void responseFetched(String response) {
							// TODO Auto-generated method stub
							resultResponse.setWithData(response,
									HttpURLConnection.HTTP_OK, null);
						}
					});
			mockHandler.getDataFormMock(requestURL, requestData);
			return resultResponse;
		}
		HttpURLConnection urlConn = null;
		try {
			urlConn = HttpURLConnectionHelper.getNewHttpURLConnectionInstanceJson(
					requestURL, requestData,
					isGzip ? RequestZipType.requestTypeGzip
							: RequestZipType.requestTypeUnzip, isAuth, requestMethod);

			LogUtil.d(TAG, "Request:" + requestURL.toString());
			LogUtil.d(TAG, "URL:" + urlConn.getURL().toString());
			LogUtil.d(TAG, "Params:" + requestData);

			if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				
				String resultString = HttpURLConnectionHelper
						.fetchHttpRequestData(urlConn);
				resultResponse.setWithData(resultString,
						HttpURLConnection.HTTP_OK, null);
				LogUtil.d(TAG, "Response:" + resultString);
//				 JSESSION
//				String key = null;
//				for (int i = 1; (key = urlConn.getHeaderFieldKey(i)) != null; i++) {
//					LogUtil.d(TAG, "JSESSION:" + urlConn.getHeaderField(i));
//				}
//				Captcha-VerifyType
//				Map<String, List<String>> map = urlConn.getHeaderFields();
//				 for (Map.Entry<String, List<String>> entry : map.entrySet())
//		            {
//					 LogUtil.d(TAG,"Key : " + entry.getKey() + " ,Value : " + entry.getValue());
//		            }
				

//				String cookieValue=urlConn.getHeaderField("Set-Cookie"); 
//				String sessionId=cookieValue.substring(0, cookieValue.indexOf(";"));
//				LogUtil.d(TAG, "sessionId:" + sessionId);
				
				// 获取和保存JSESSIONID
				String cookieValue=urlConn.getHeaderField("Set-Cookie"); 
				if(cookieValue != null){
                	Constant.JSESSIONID = cookieValue.substring(cookieValue.indexOf("=") + 1, cookieValue.indexOf(";"));
                }
				LogUtil.d(TAG, "JSESSIONID:" + Constant.JSESSIONID);
				
				// 获取和保存Captcha-VerifyType
				String cookieValue2=urlConn.getHeaderField("Captcha-VerifyType"); 
				if(cookieValue2 != null){
                	Constant.verifyType = cookieValue2.substring(cookieValue2.indexOf(":") + 1);
                }
				LogUtil.d(TAG, "Captcha-VerifyType:" + Constant.verifyType);

			} else if (urlConn.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) {

				String resultString = null;
				InputStream in = urlConn.getErrorStream();
				resultString = StreamUtil.convertStreamToString(in);
				in.close();
				resultResponse
						.setWithData(resultString, urlConn.getResponseCode(),
								urlConn.getResponseMessage());
				LogUtil.d(TAG + "返回ResponseCode：401", urlConn.getResponseCode()
						+ ":" + urlConn.getResponseMessage() + resultString);
			}
			/*
			 * 预留接口
			 */
			// else if (urlConn.getResponseCode() ==
			// HttpURLConnection.HTTP_BAD_REQUEST) {
			// LogUtil.d("HttpError",
			// urlConn.getResponseCode() + ":"
			// + urlConn.getResponseMessage());
			// resultResponse.setWithData("", urlConn.getResponseCode(),
			// urlConn.getResponseMessage());
			// } else if (urlConn.getResponseCode() == 460) {
			// LogUtil.d("HttpError",
			// urlConn.getResponseCode() + ":"
			// + urlConn.getResponseMessage());
			// resultResponse.setWithData("", urlConn.getResponseCode(),
			// urlConn.getResponseMessage());
			// }
			else {
				LogUtil.d("HttpError", urlConn.getResponseCode() + ":"
						+ urlConn.getResponseMessage());
				resultResponse.setWithData("", urlConn.getResponseCode(),
						urlConn.getResponseMessage());
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			LogUtil.e(TAG, "Connection Error");
			e.printStackTrace();
		} finally {
			urlConn.disconnect();
		}
		return resultResponse;
	}

	

	/**
	 * 发送http请求,请求数据无压缩
	 * 
	 * @param requestData
	 *            请求数据为JSON格式字符串
	 * @param requestURL
	 *            接口地址
	 */
	public static NetworkResponse httpRequest(String requestURL,
			String requestData, int requestMethod) {
		return doHttpRequest(requestURL, requestData, false, false, requestMethod);
	}
	
	
	/**
	 * 发送http请求,请求数据无压缩
	 * 
	 * @param requestData
	 *            请求数据为JSON格式字符串
	 * @param requestURL
	 *            接口地址
	 */
	public static NetworkResponse httpRequest(String requestURL,
			String requestData) {
		return doHttpRequest(requestURL, requestData, false, false, RequestMethod.METHOD_POST);
	}
	

	/**
	 * 发送http请求,请求数据GZip压缩
	 * 
	 * @param requestData
	 *            请求数据为JSON格式字符串
	 * @param requestURL
	 *            接口地址
	 */
	public static NetworkResponse httpRequestByGZip(String requestURL,
			String requestData, int requestMethod) {
		return doHttpRequest(requestURL, requestData, false, true,requestMethod);
	}

	/**
	 * 发送http请求,用于OpenAPI鉴权
	 * 
	 * @param requestData
	 *            请求数据为JSON格式字符串
	 * @param requestURL
	 *            接口地址
	 * 
	 * @return 请求结果
	 */
	public static NetworkResponse httpRequestAuth(String requestURL,
			String requestData, int requestMethod) {
		return doHttpRequest(requestURL, requestData, true, false,requestMethod);
	}

	/**
	 * 发送https请求,请求数据无压缩
	 * 
	 * @param requestData
	 *            请求数据为JSON格式字符串
	 */
	public static NetworkResponse httpsRequest(String requestURL,
			String requestData, int requestMethod) {
		return doHttpRequest(requestURL, requestData, false, false, requestMethod);
	}

	/**
	 * 发送https请求,请求数据GZip压缩
	 * 
	 * @param requestData
	 *            请求数据为JSON格式字符串
	 */
	public static NetworkResponse httpsRequestByGZip(String requestURL,
			String requestData, int requestMethod) {
		return doHttpRequest(requestURL, requestData, false, true,requestMethod);
	}

	/**
	 * 发送https请求,用于OpenAPI鉴权
	 * 
	 * @param requestData
	 *            参数
	 * @param method
	 *            接口名
	 * 
	 * @return 请求结果
	 */
	public static NetworkResponse httpsRequestAuth(String requestData,
			String requestURL, int requestMethod) {
		return doHttpRequest(requestURL, requestData, true, false,requestMethod);
	}

	/**
	 * 表单提交
	 * 
	 * @requestURL 路径
	 * @param params参数
	 * @param file
	 *            图片
	 */
	public static NetworkResponse httpRequestByForm(String requestURL,
			HashMap<String, String> params, File file, boolean isGzip) {
		final NetworkResponse resultResponse = new NetworkResponse();
		HttpURLConnection urlConn = null;
		try {
			// HeadImg headImg = new Gson().fromJson(params, HeadImg.class);
			// HashMap<String, String> pars = new HashMap<String, String>();
			// pars.put("userId", headImg.userId);
			// pars.put("file", headImg.file);
			urlConn = HttpURLConnectionHelper
					.getNewHttpURLFormConnectionInstance(requestURL, params,
							isGzip ? RequestZipType.requestTypeGzip
									: RequestZipType.requestTypeUnzip, file);
			LogUtil.d(TAG, "Request:" + requestURL.toString());
			LogUtil.d(TAG, "URL:" + urlConn.getURL().toString());
			LogUtil.d(TAG, "Params:" + params.toString());
			if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				String resultString = HttpURLConnectionHelper
						.fetchHttpRequestData(urlConn);
				resultResponse.setWithData(resultString,
						HttpURLConnection.HTTP_OK, null);
				LogUtil.d(TAG, "Response:" + resultString);
			} else {
				LogUtil.d("HttpError", urlConn.getResponseCode() + ":"
						+ urlConn.getResponseMessage());
				resultResponse.setWithData("", urlConn.getResponseCode(),
						urlConn.getResponseMessage());
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			urlConn.disconnect();
		}
		return resultResponse;
	}

	/**
	 * 下载操作
	 * 
	 * @param urlString
	 * @return
	 */
	public static NetworkResponse httpRequestDownload(String filePath,
			String urlString, UpdateUtil updateUtil) {
		final NetworkResponse resultResponse = new NetworkResponse();
		LogUtil.e(TAG, "Download URL:" + urlString);
		URL url;
		try {
			url = new URL(urlString);

			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			InputStream is = conn.getInputStream();
			File file = new File(filePath);
			if (file.exists()) {
				// 删除上次更新的APK包
				file.delete();
			}
			FileOutputStream fos = new FileOutputStream(file);
			BufferedInputStream bis = new BufferedInputStream(is);
			int total = conn.getContentLength();
			int progress = 0;
			byte[] buffer = new byte[64];
			int len;
			while ((len = bis.read(buffer)) != -1) {
				fos.write(buffer, 0, len);
				progress += len;
				if (null != updateUtil) {
					updateUtil.downloadProgress((progress / (float) total));
				}
			}
			bis.close();
			fos.close();
			is.close();
			conn.disconnect();
			// 保证文件的完整性
			if (progress == total) {
				resultResponse.setWithData(null, HttpURLConnection.HTTP_OK,
						null);
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {

		}

		return resultResponse;
	}
	
	
	public static NetworkResponse httpRequestVideo(String urlString,String videoName) {
		final NetworkResponse resultResponse = new NetworkResponse();
		
		File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"
				+ "learningkitesCache" + "/" + videoName+".mp4" );
		if (file.exists()) {
			resultResponse.setWithData(file.getAbsolutePath(), HttpURLConnection.HTTP_OK,
					null);
			return resultResponse;
		}
		
		URL url;
		try {
			url = new URL(urlString);

			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			LogUtil.e(TAG, "Download URL:" + urlString);
			if(null != Constant.JSESSIONID){
				conn.setRequestProperty("Cookie", "JSESSIONID =" + Constant.JSESSIONID);
            }
			
			InputStream is = conn.getInputStream();
			LogUtil.e(TAG, "" + conn.getResponseCode());
			Map<String, List<String>> map = conn.getHeaderFields();
			 for (Map.Entry<String, List<String>> entry : map.entrySet())
	            {
				 LogUtil.e(TAG,"Key : " + entry.getKey() + " ,Value : " + entry.getValue());
	            }
			
			 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
				File videoPath = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"
								+ "learningkitesCache");
				if (!videoPath.exists()) {
					videoPath.mkdir(); 
				}
				File videoCache = new File(videoPath, videoName+".mp4");
				FileOutputStream fos = new FileOutputStream(videoCache);
				BufferedInputStream bis = new BufferedInputStream(is);
				int total = conn.getContentLength();
				byte[] buffer = new byte[64];
				int len;
				while ((len = bis.read(buffer)) != -1) {
					fos.write(buffer, 0, len);
				}
				bis.close();
				fos.close();
				is.close();
				conn.disconnect();
				LogUtil.e(TAG, videoCache.length() + "bytes ," + videoCache.getAbsolutePath());
				resultResponse.setWithData(videoCache.getAbsolutePath(), HttpURLConnection.HTTP_OK,
							null);
			}
			
			
//			if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//				file = new File(Environment.getExternalStorageDirectory()
//	                    .getAbsolutePath()
//	                    + "/VideoCache/"
//	                    + System.currentTimeMillis() + ".mp4");
//				}
//			File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/VideoCache/");
//			if (!file.exists()) {  
//                file.mkdir();  
//            }
//			file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/VideoCache/" + System.currentTimeMillis() + ".mp4");
//			
//			FileOutputStream fos = new FileOutputStream(file);
//			BufferedInputStream bis = new BufferedInputStream(is);
//			int total = conn.getContentLength();
//			byte[] buffer = new byte[64];
//			int len;
//			while ((len = bis.read(buffer)) != -1) {
//				fos.write(buffer, 0, len);
//			}
//			bis.close();
//			fos.close();
//			is.close();
//			conn.disconnect();
//			LogUtil.e(TAG, "" + file.length() + file.getAbsolutePath());
//			resultResponse.setWithData(file.getAbsolutePath(), HttpURLConnection.HTTP_OK,
//						null);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {

		}

		return resultResponse;
	}

	/**
	 * HttpPost方式请求,返回cookie
	 * 
	 * @param url
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public static NetworkResponse requestByHttpPostWithCookie(String url,
			Map<String, String> params) throws Exception {
		final NetworkResponse resultResponse = new NetworkResponse();
		String result = null;
		// 新建HttpPost对象
		HttpPost httpPost = new HttpPost(url);
		// Post参数
		List<NameValuePair> parameters = new ArrayList<NameValuePair>();
		for (Map.Entry entry : params.entrySet()) {
			parameters.add(new BasicNameValuePair(entry.getKey().toString(),
					entry.getValue().toString()));
		}
		// 设置字符集
		HttpEntity entity = new UrlEncodedFormEntity(parameters, HTTP.UTF_8);
		// 设置参数实体
		httpPost.setEntity(entity);
		// httpPost.setHeader("Accept", "application/json");
		// httpPost.setHeader("Content-Type", "application/json");
		// 获取HttpClient对象
		DefaultHttpClient httpClient = new DefaultHttpClient();
		// 获取HttpResponse实例
		HttpResponse httpResp = httpClient.execute(httpPost);
		// 判断是够请求成功
		if (httpResp.getStatusLine().getStatusCode() == 200) {
			// 获取返回的数据
			result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
			List<Cookie> cookies = httpClient.getCookieStore().getCookies();

			resultResponse.setWithData(result, HttpURLConnection.HTTP_OK, null,
					cookies);
			LogUtil.d(TAG, "HttpPost方式请求成功，返回数据如下：" + result);
		} else {
			LogUtil.d(TAG, "HttpPost方式请求失败");
		}
		return resultResponse;
	}
}